#include "StdAfx.h"
#include "PlayMediaGraph.h"


CPlayMediaGraph::CPlayMediaGraph(void)
{
}


CPlayMediaGraph::~CPlayMediaGraph(void)
{
}


bool CPlayMediaGraph::Create()
{
	if (!pGraph)
	{
		if (SUCCEEDED(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
			IID_IGraphBuilder, (void **)&pGraph)))
		{
			AddToObjectTable();
			return true;
		}
		pGraph = 0;
	}
	return false;
}

bool CPlayMediaGraph::QueryInterfaces()
{
	if (pGraph)
	{
		HRESULT hr = NOERROR;
		hr|=pGraph->QueryInterface(IID_IMediaControl,(void**)&pMediaControl);
		hr|=pGraph->QueryInterface(IID_IMediaEventEx,(void**)&pMediaEvent);
		hr|=pGraph->QueryInterface(IID_IBasicVideo,(void**)&pBasicVideo);
		hr|=pGraph->QueryInterface(IID_IBasicAudio,(void**)&pBasicAudio);
		hr|=pGraph->QueryInterface(IID_IVideoWindow,(void**)&pWindow);
		hr|=pGraph->QueryInterface(IID_IMediaSeeking,(void**)&pSeeking);
		if(pSeeking)
		{
			pSeeking->SetTimeFormat(&TIME_FORMAT_MEDIA_TIME);
		}
		return SUCCEEDED(hr);
	}
	return false;
}


// Create Capture Show
bool CPlayMediaGraph::CreateCaptureShow(HWND hwnd)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());
	HRESULT hr = NOERROR;
	if(pWindow)
	{
		//RECT rc;
		hr=pWindow->put_Owner((OAHWND)hwnd);
		RECT rect;
		::GetWindowRect(hwnd,&rect);
		// Use helper function to position video window in client rect 
		// of main application window
		pWindow->SetWindowPosition(0, 0, rect.right, rect.bottom);
		hr=pWindow->put_Visible(OATRUE);
		hr=pWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS);
	}
	return TRUE;
}

bool CPlayMediaGraph::RenderFile(const std::wstring & filename)
{
	if(!pGraph)
	{
		return false;
	}
	HRESULT hr = NOERROR;
	hr|=pGraph->RenderFile(filename.c_str(),NULL);
	return true;
}

//////////////////////// For GraphEdit Dubug purpose /////////////////////////////
void CPlayMediaGraph::AddToObjectTable(void)
{
	IMoniker * pMoniker = 0;
    IRunningObjectTable * objectTable = 0;
    if (SUCCEEDED(GetRunningObjectTable(0, &objectTable))) 
	{
		WCHAR wsz[256];
		swprintf(wsz, L"FilterGraph %08p pid %08x", pGraph, GetCurrentProcessId());
		HRESULT hr = CreateItemMoniker(L"!", wsz, &pMoniker);
		if (SUCCEEDED(hr)) 
		{
			hr = objectTable->Register(0, pGraph, pMoniker, &mObjectTableEntry);
			pMoniker->Release();
		}
		objectTable->Release();
	}
}

void CPlayMediaGraph::RemoveFromObjectTable(void)
{
	IRunningObjectTable * objectTable = 0;
    if (SUCCEEDED(GetRunningObjectTable(0, &objectTable))) 
	{
        objectTable->Revoke(mObjectTableEntry);
        objectTable->Release();
		mObjectTableEntry = 0;
    }
}



bool CPlayMediaGraph::Run(void)
{
	if (pGraph && pMediaControl)
	{
		if (!IsRunning())
		{
			if (SUCCEEDED(pMediaControl->Run()))
			{
				return true;
			}
		}
		else
		{
			return true;
		}
	}
	return false;
}

bool CPlayMediaGraph::Stop(void)
{
	if (pGraph && pMediaControl)
	{
		if (!IsStopped())
		{	
			if (SUCCEEDED(pMediaControl->Stop()))
			{
				return true;
			}
		}
		else
		{
			return true;
		}
	}
	return false;
}

bool CPlayMediaGraph::Pause(void)
{
	if (pGraph && pMediaControl)
	{
		if (!IsPaused())
		{	
			if (SUCCEEDED(pMediaControl->Pause()))
			{
				return true;
			}
		}
		else
		{
			return true;
		}
	}
	return false;
}

bool CPlayMediaGraph::IsRunning(void)
{
	if (pGraph && pMediaControl)
	{
		OAFilterState state = State_Stopped;
		if (SUCCEEDED(pMediaControl->GetState(10, &state)))
		{
			return state == State_Running;
		}
	}
	return false;
}

bool CPlayMediaGraph::IsStopped(void)
{
	if (pGraph && pMediaControl)
	{
		OAFilterState state = State_Stopped;
		if (SUCCEEDED(pMediaControl->GetState(10, &state)))
		{
			return state == State_Stopped;
		}
	}
	return false;
}

bool CPlayMediaGraph::IsPaused(void)
{
	if (pGraph && pMediaControl)
	{
		OAFilterState state = State_Stopped;
		if (SUCCEEDED(pMediaControl->GetState(10, &state)))
		{
			return state == State_Paused;
		}
	}
	return false;
}


// SetCurrentPosition
bool CPlayMediaGraph::SetCurrentPosition(double inPosition)
{
	if(pSeeking)
	{
		__int64 one = 10000000;
		__int64 position = (__int64) (one * inPosition);
		HRESULT hr = NOERROR;
		hr|=pSeeking->SetPositions(&position,AM_SEEKING_AbsolutePositioning,
		NULL,AM_SEEKING_NoPositioning);
		return SUCCEEDED(hr);
	}
	return false;
}


void CPlayMediaGraph::ResetView(HWND hwnd)
{
	//if(pWindow == NULL)
	//{
	//	return;
	//}
	//RECT rect;
	//::GetWindowRect(hwnd,&rect);
	//// Use helper function to position video window in client rect 
	//// of main application window
	//pWindow->SetWindowPosition(0, 0, rect.right, rect.bottom);
}